home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
UNIX.C
< prev
next >
Wrap
Text File
|
1990-07-12
|
18KB
|
872 lines
/* OS- and machine-dependent stuff for UNIX */
/* collected from a lot of other stuff from different releases of the package */
/* Written by Mikel Matthews, N9DVG */
/* SYS5 stuff added by Jere Sandidge, K4FUM */
/* cleanup and adaption into NETCHL by PE1CHL */
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <termio.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/ndir.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <prototypes.h>
#include "global.h"
#include "config.h"
#include "mbuf.h"
#include "internet.h"
#include "iface.h"
#include "cmdparse.h"
#include "timer.h"
#include "environ.h"
#include "asy.h"
#include "unix.h"
#ifndef B19200
#define B19200 EXTA
#endif
#ifndef B38400
#define B38400 EXTB
#endif
#if (defined(FD_SETSIZE) && !defined(M_I86MM))
#define SELECT /* we can use the select() call */
# ifdef FD_ZERO
# define bzero(s,n) memset(s,0,n) /* there is no bzero() in the lib! */
# define NUL_SET {0}
# else
typedef unsigned long fd_set; /* equivalents of FD_xxx macros */
# define FD_ZERO(fdsp) *(fdsp) = 0
# define FD_SET(fd,fdsp) *(fdsp) |= (1 << (fd))
# define FD_CLR(fd,fdsp) *(fdsp) &= ~(1 << (fd))
# define FD_ISSET(fd,fdsp) (*(fdsp) & (1 << (fd)))
# define NUL_SET 0
# endif
#endif
struct asy asy[ASY_MAX];
struct interface *ifaces;
unsigned nasy = 0; /* number of ASY interfaces */
#ifdef SERVERS
extern FILE *logfp; /* log file pointer */
extern char logname[]; /* log file name */
#endif
#ifdef TRACE
extern FILE *trfp; /* trace file pointer */
extern char trname[]; /* trace file name */
#endif
#ifdef IP
extern struct mbuf *loopq;
#endif
#ifdef AX25
extern struct mbuf *axloopq;
#endif
static struct termio saved_termio; /* termio on program startup */
static struct termio our_termio; /* termio during program run */
#ifdef SELECT
static char *envselect; /* options passed using SELECT envvar */
static int noselect = 0; /* # of fd's NOT supporting select */
static int maxfd = 0; /* # of fd's for select() */
static fd_set port_set = NUL_SET; /* set containing all serial devices */
static fd_set read_set = NUL_SET; /* returned set from last select() */
static prg_busy = 0; /* set when busy */
#endif
static char ttbuf[BUFSIZ]; /* buffer used for stdout buffering */
/* Called at startup time to set up console I/O */
ioinit()
{
#ifdef SELECT
fd_set fdset; /* trial set for select */
struct timeval timeout;
#endif
setbuf(stdout,ttbuf); /* buffering for stdout */
tzset(); /* init the timezone variable */
ioctl(0,TCGETA,&saved_termio); /* read and save termio state */
/* copy termio and drop input processing, echo, and INTR signal */
/* the VMIN/VTIME will be set up for immediate return when no key */
ASSIGN(our_termio,saved_termio);
our_termio.c_lflag &= ~(ICANON|ECHO);
our_termio.c_cc[VINTR] = 0xff;
our_termio.c_cc[VMIN] = 0;
our_termio.c_cc[VTIME] = 0;
#ifdef SELECT
envselect = getnenv("SELECT"); /* get SELECT var settings */
if (strchr(envselect,'k') != NULL) /* select() on keyboard? */
{
/* check if stdin can use select() */
FD_ZERO(&fdset); /* setup an fd_set for stdin */
FD_SET(0,&fdset);
timeout.tv_sec = timeout.tv_usec = 0;
if (select(1,&fdset,NULL,NULL,&timeout) < 0)
{
if (errno == EINVAL) /* no select() support */
printf("warning: stdin device does not support select()\n");
else
perror("stdin select");
noselect++;
}
else /* select() went okay */
{
maxfd = 1; /* select on fd #0 */
FD_SET(0,&port_set); /* enter stdin in the select set */
our_termio.c_cc[VMIN] = 1; /* can wait on read() */
our_termio.c_cc[VTIME] = 2;
}
}
else
noselect++; /* no select on stdin */
#endif
ioctl(0,TCSETA,&our_termio); /* set our termio values */
}
/* Called just before exiting to restore console state */
iostop()
{
while(ifaces != NULLIF){
/* first flush the interface's buffers */
while(ifaces->recv != NULLVFP && (*ifaces->recv)(ifaces))
;
if(ifaces->stop != NULLFP)
(*ifaces->stop)(ifaces);
ifaces = ifaces->next;
}
ioctl(0,TCSETAW,&saved_termio); /* reset to original state */
}
/* Spawn subshell */
doshell(argc,argv)
int argc;
char *argv[];
{
char *command,**envp;
int ret;
#ifdef SERVERS
if (logfp != NULLFILE) /* logging to file? */
fclose(logfp); /* close the logfile */
#endif
#ifdef TRACE
if (trfp != stdout) /* trace to file? */
fclose(trfp); /* close it during shell exec */
#endif
fflush(stdout);
ioctl(0,TCSETAW,&saved_termio); /* set original terminal mode */
if((command = getenv("SHELL")) == NULLCHAR)
command = "/bin/sh"; /* default command interpreter */
envp = make_env(); /* create envinronment array */
switch (fork()) /* spawn a subprocess */
{
case -1: /* an error occurred... */
perror("fork");
ret = -1;
break;
case 0: /* this is the child */
execve(command,argv,envp);
perror(command);
exit(1);
default: /* this is the parent */
wait(&ret); /* wait for child to terminate */
break;
}
ioctl(0,TCSETAW,&our_termio); /* our terminal mode again */
free_env(); /* free the envp and temp env */
#ifdef SERVERS
if (logfp != NULLFILE) /* re-open logfile if it was open */
logfp = fopen(logname,"a+");
#endif
#ifdef TRACE
if (trfp != stdout) /* re-open tracefile if not stdout */
if ((trfp = fopen(trname,"a+")) == NULLFILE)
trfp = stdout;
#endif
if (ret != 0)
return -1;
return 0;
}
/* checks the time then ticks and updates ISS */
static time_t clkval = 0;
void
check_time()
{
int32 iss();
time_t ntime;
int maxticks = SEC2TICK(15); /* upper limit on delayed ticks */
struct tms tms; /* dummy required by times() */
if(clkval == 0){
/* Executed only once */
clkval = times(&tms);
return;
}
ntime = times(&tms); /* read elapsed time */
while(ntime != clkval){ /* Handle possibility of several missed ticks */
#ifdef IP
icmpclk(); /* Call this one before tick */
#endif
tick();
#ifdef IP
(void)iss();
#endif
if(maxticks--) /* check limit on ticks to handle */
clkval++;
else
clkval = ntime; /* ignore any remaining ticks */
}
}
/* Read characters from the keyboard, translating them to internal codes.
* If none are ready, return -1
* This piece of code crudely assumes that you are on an ANSI terminal...
*/
int
kbread()
{
int c;
#ifdef SELECT
struct timeval timeout;
if (stdin->_cnt == 0 && /* no buffered characters? */
maxfd > 0) /* select() allowed? */
{
read_set = port_set;
timeout.tv_sec = timeout.tv_usec = 0;
#ifdef IP
if (loopq == NULLBUF) /* nothing on IP loopback? */
#endif
#ifdef AX25
if (axloopq == NULLBUF) /* nothing on AX.25 loopb? */
#endif
if (noselect || prg_busy) /* reason to stay awake? */
timeout.tv_usec = 20000; /* short sleeptime */
else
timeout.tv_sec = 1; /* sleep for a long time */
prg_busy = 1; /* assume we are busy */
if (select(maxfd,&read_set,NULL,NULL,&timeout) >= 0)
{
#ifdef DEBUG
int i;
printf("select:");
for (i = 0; i < maxfd; i++)
if (FD_ISSET(i,&read_set))
printf(" %d",i);
printf("\n");
fflush(stdout);
#endif
}
else
{
#ifdef DEBUG
perror("select:");
#endif
return -1; /* error in select() */
}
if (FD_ISSET(0,&port_set) && !FD_ISSET(0,&read_set))
return -1; /* select() says no input available */
}
#endif
if((c = getchar()) == EOF)
return -1; /* no input available */
if(c == 0x1b){ /* ESC character? */
/* Lead-in to a special char */
if(getchar() != '[')
return 0x1b;
switch(c = getchar())
{
case 'M': /* F-1 key */
c = -11;
break;
case 'N': /* F-2 key */
c = -10;
break;
case 'O': /* F-3 key */
c = -9;
break;
case 'P': /* F-4 key */
c = -8;
break;
case 'Q': /* F-5 key */
c = -7;
break;
case 'R': /* F-6